package com.service.scheduling.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.*;
import com.service.dao.mapper.JournalAccountMapper;
import com.service.dao.mapper.MemberMapper;
import com.service.dao.model.MemberMiningOrder;
import com.service.dao.model.OrderProductHrCombo;
import com.service.dao.model.OrderProductHrComboPadding;
import com.service.scheduling.dto.MemberStoreChange;
import com.service.scheduling.service.*;
import com.service.scheduling.support.MemberCacheUtils;
import com.service.scheduling.support.MemberStoreLockUtils;
import com.service.scheduling.utils.DateUtil;
import com.service.scheduling.utils.MemCacheNoTran;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 线性释放收益定时器
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class HrFrostReleaseTask {

	@Autowired
	private MemberCacheUtils memberCacheUtils;
	@Autowired
	private MemberMapper memberMapper;
	@Autowired
	private MemberStoreLockUtils memberStoreLockUtils;
	@Autowired
	private SysConfigService sysConfigService;
	@Autowired
	private MemberStoreService memberStoreService;
	@Autowired
	private MemberMiningOrderService memberMiningOrderService;
	@Autowired
	private ProductHrComboService productHrComboService;
	@Autowired
	private JournalAccountMapper journalAccountMapper;
	@Autowired
	private ConfigService configService;
	@Autowired
	private MemberMiningOrderService miningOrderService;
	@Autowired
	private OrderProductHrComboPaddingService orderProductHrComboPaddingService;
	@Autowired
	private OrderProductHrComboService orderProductHrComboService;

	@Autowired
	private SysQuotesIpfxService sysQuotesIpfxService;

	@Autowired
	private MemCacheNoTran memCache;

	private static BigDecimal baseNum = new BigDecimal(100L);


	/**
	 * 线性释放定时任务
	 */
	@Scheduled(cron = "0 0 0 * * ?")
	public void doCalculate() {
		log.info("FIL线性释放定时任务-开始");
		String minerStatus = configService.getByConfigName(ConfigConstants.MINER_STATUS).getConfValue();
		if (MinerStatusEnum.OFF.equals(minerStatus)) {
			log.info("矿机暂停运行......");
			return;
		}
		Date currentDate = new Date();
		String pattern = "yyyy-MM-dd";
		String currentDateStr = DateFormatUtils.format(currentDate, pattern);
		Date yesterday = DateUtil.getDayOfStart(DateUtils.addDays(currentDate, 0));

		List<MemberMiningOrder> miningOrderList = miningOrderService.listUnFinishedOrder();
		if (ObjectUtils.isEmpty(miningOrderList)) {
			log.info("今日暂无算力线性释放订单");
			return;
		}
		String yesterdayStr = DateFormatUtils.format(yesterday, pattern);

		List<Integer> endList = Lists.newArrayList();

		miningOrderList.parallelStream().forEach(item -> {
			if (ObjectUtils.nullSafeEquals(item.getIsFinish(), MemberFrostMiningEnum.UNFINISHED.getCode())
					&& item.getStartTime().after(currentDate)) {
				log.info("线性释放订单<orderId:{}>还未开始", item.getId());
				return;
			}
			if (ObjectUtils.nullSafeEquals(item.getIsFinish(), MemberFrostMiningEnum.COMPLETED.getCode())) {
				log.info("线性释放订单<orderId:{}>已结束", item.getId());
				endList.add(item.getId());
				return;
			}
			if (item.getFrostNum().compareTo(item.getTotalRelease()) == 0) {
				log.warn("<{}>线性释放订单<orderId:{}>已达释放上限", currentDate, item.getId());
				return;
			}
			if (item.getFrostNum().compareTo(item.getTotalRelease()) < 0) {
				log.error("<{}>线性释放订单<orderId:{}>已达释放异常", currentDate, item.getId());
				return;
			}
			if (item.getReleaseDay() == 179) {
				log.info("线性释放订单<orderId:{}>释放最后一天<{}>", item.getId(), currentDate);
				endList.add(item.getId());
			}
			if (!ObjectUtils.isEmpty(memberStoreService.getFrostMiningRecord(item.getMemberId(), item.getId(), currentDate))) {
				log.info("线性释放订单<orderId:{}>,今日<{}>已发昨日<{}>挖矿所得", item.getId(), currentDateStr, yesterdayStr);
				return;
			}
			//计算释放金额
			BigDecimal dailyReleaseNum = item.getFrostNum().divide(new BigDecimal(item.getLockDay()), 6, BigDecimal.ROUND_DOWN);
			boolean isLock = memberStoreLockUtils.lock(item.getMemberId(), CoinsEnum.FIL.getCode());
			if (!isLock) {
				return;
			}
			if (dailyReleaseNum.compareTo(BigDecimal.ZERO) <= 0) {
				return;
			}
			//更新订单累计收益
			OrderProductHrComboPadding combo = null;
			if (!ObjectUtils.isEmpty(item.getOrderId())) {
				combo = orderProductHrComboPaddingService.getOne(new QueryWrapper<OrderProductHrComboPadding>().lambda()
						.eq(OrderProductHrComboPadding::getId, item.getOrderId()));
			}
			memberStoreService.changeMemberStore(
					MemberStoreChange.builder()
							.memberId(item.getMemberId())
							.coinsId(CoinsEnum.FIL.getCode())
							.coinsName(CoinsEnum.FIL.getName())
							.jaType(MemberJAType.MINING_FROST)
							.orderId(ObjectUtils.isEmpty(combo) ? null : combo.getId())
							.changeNum(dailyReleaseNum)
							.remark(yesterdayStr + MemberJAType.MINING_FROST.getMsg())
							.build());
			memberStoreLockUtils.unlock(item.getMemberId(), CoinsEnum.FIL.getCode());
			//更新线性释放订单记录信息
			item.setTotalRelease(item.getTotalRelease().add(dailyReleaseNum));
			item.setReleaseDay(item.getReleaseDay() + 1);
			miningOrderService.updateById(item);
			if (!ObjectUtils.isEmpty(combo)) {
				combo.setTotalIncome(combo.getTotalIncome().add(dailyReleaseNum));
				orderProductHrComboPaddingService.updateById(combo);
			}
			//根据填充订单反向查询算力订单信息
			OrderProductHrCombo orderProductHrCombo = orderProductHrComboService.getById(combo.getHrOrderId());
			if (!ObjectUtils.isEmpty(orderProductHrCombo)) {
				orderProductHrCombo.setAccumulatedIncome(orderProductHrCombo.getAccumulatedIncome().add(dailyReleaseNum));
				orderProductHrComboService.updateById(orderProductHrCombo);
			}
		});
		log.info("FIL线性释放定时任务-结束");
	}
}
